home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!zephyr.ens.tek.com!tekred!saab!billr
- From: billr@saab.CNA.TEK.COM (Bill Randle)
- Newsgroups: comp.sources.games
- Subject: v11i011: tinymud2 - user-extendible multi-user adventure (v1.5.4), Part07/10
- Message-ID: <6056@tekred.CNA.TEK.COM>
- Date: 30 Jul 90 16:46:06 GMT
- Sender: news@tekred.CNA.TEK.COM
- Lines: 2237
- Approved: billr@saab.CNA.TEK.COM
-
- Submitted-by: James Aspnes <asp@cs.cmu.edu>
- Posting-number: Volume 11, Issue 11
- Archive-name: tinymud2/Part07
- Supersedes: tinymud: Volume 8, Issue 80-83
-
-
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 7 (of 10)."
- # Contents: db.c game.c restart-cmu tinymud.tex
- # Wrapped by billr@saab on Fri Jul 27 15:27:48 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'db.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'db.c'\"
- else
- echo shar: Extracting \"'db.c'\" \(9028 characters\)
- sed "s/^X//" >'db.c' <<'END_OF_FILE'
- X#include "copyright.h"
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X
- X#include "db.h"
- X#include "config.h"
- X
- Xstruct object *db = 0;
- Xdbref db_top = 0;
- X
- X#ifdef TEST_MALLOC
- Xint malloc_count = 0;
- X#endif /* TEST_MALLOC */
- X
- X#ifndef DB_INITIAL_SIZE
- X#define DB_INITIAL_SIZE 10000
- X#endif /* DB_INITIAL_SIZE */
- X
- X#ifdef DB_DOUBLING
- X
- Xdbref db_size = DB_INITIAL_SIZE;
- X#endif /* DB_DOUBLING */
- X
- Xconst char *alloc_string(const char *string)
- X{
- X char *s;
- X
- X /* NULL, "" -> NULL */
- X if(string == 0 || *string == '\0') return 0;
- X
- X if((s = (char *) malloc(strlen(string)+1)) == 0) {
- X abort();
- X }
- X strcpy(s, string);
- X return s;
- X}
- X
- X#ifdef DB_DOUBLING
- X
- Xstatic void db_grow(dbref newtop)
- X{
- X struct object *newdb;
- X
- X if(newtop > db_top) {
- X db_top = newtop;
- X if(!db) {
- X /* make the initial one */
- X db_size = DB_INITIAL_SIZE;
- X if((db = (struct object *)
- X malloc(db_size * sizeof(struct object))) == 0) {
- X abort();
- X }
- X }
- X
- X /* maybe grow it */
- X if(db_top > db_size) {
- X /* make sure it's big enough */
- X while(db_top > db_size) db_size *= 2;
- X if((newdb = (struct object *)
- X realloc((void *) db,
- X db_size * sizeof(struct object))) == 0) {
- X abort();
- X }
- X db = newdb;
- X }
- X }
- X}
- X
- X#else /* DB_DOUBLING */
- X
- Xstatic void db_grow(dbref newtop)
- X{
- X struct object *newdb;
- X
- X if(newtop > db_top) {
- X db_top = newtop;
- X if(db) {
- X if((newdb = (struct object *)
- X realloc((void *) db,
- X db_top * sizeof(struct object))) == 0) {
- X abort();
- X }
- X db = newdb;
- X } else {
- X /* make the initial one */
- X if((db = (struct object *)
- X malloc(DB_INITIAL_SIZE * sizeof(struct object))) == 0) {
- X abort();
- X }
- X }
- X }
- X}
- X#endif /* DB_DOUBLING */
- X
- Xdbref new_object(void)
- X{
- X dbref newobj;
- X struct object *o;
- X
- X newobj = db_top;
- X db_grow(db_top + 1);
- X
- X /* clear it out */
- X o = db+newobj;
- X o->name = 0;
- X o->description = 0;
- X o->location = NOTHING;
- X o->contents = NOTHING;
- X o->exits = NOTHING;
- X o->next = NOTHING;
- X o->key = TRUE_BOOLEXP;
- X o->fail_message = 0;
- X o->succ_message = 0;
- X o->ofail = 0;
- X o->osuccess = 0;
- X o->owner = NOTHING;
- X o->pennies = 0;
- X /* flags you must initialize yourself */
- X o->password = 0;
- X
- X return newobj;
- X}
- X
- X#define DB_MSGLEN 512
- X
- Xvoid putref(FILE *f, dbref ref)
- X{
- X fprintf(f, "%d\n", ref);
- X}
- X
- Xstatic void putstring(FILE *f, const char *s)
- X{
- X if(s) {
- X fputs(s, f);
- X }
- X putc('\n', f);
- X}
- X
- Xstatic void putbool_subexp(FILE *f, struct boolexp *b)
- X{
- X switch(b->type) {
- X case BOOLEXP_AND:
- X putc('(', f);
- X putbool_subexp(f, b->sub1);
- X putc(AND_TOKEN, f);
- X putbool_subexp(f, b->sub2);
- X putc(')', f);
- X break;
- X case BOOLEXP_OR:
- X putc('(', f);
- X putbool_subexp(f, b->sub1);
- X putc(OR_TOKEN, f);
- X putbool_subexp(f, b->sub2);
- X putc(')', f);
- X break;
- X case BOOLEXP_NOT:
- X putc('(', f);
- X putc(NOT_TOKEN, f);
- X putbool_subexp(f, b->sub1);
- X putc(')', f);
- X break;
- X case BOOLEXP_CONST:
- X fprintf(f, "%d", b->thing);
- X break;
- X default:
- X break;
- X }
- X}
- X
- Xvoid putboolexp(FILE *f, struct boolexp *b)
- X{
- X if(b != TRUE_BOOLEXP) {
- X putbool_subexp(f, b);
- X }
- X putc('\n', f);
- X}
- X
- Xint db_write_object(FILE *f, dbref i)
- X{
- X struct object *o;
- X
- X o = db + i;
- X putstring(f, o->name);
- X putstring(f, o->description);
- X putref(f, o->location);
- X putref(f, o->contents);
- X putref(f, o->exits);
- X putref(f, o->next);
- X putboolexp(f, o->key);
- X putstring(f, o->fail_message);
- X putstring(f, o->succ_message);
- X putstring(f, o->ofail);
- X putstring(f, o->osuccess);
- X putref(f, o->owner);
- X putref(f, o->pennies);
- X putref(f, o->flags);
- X putstring(f, o->password);
- X
- X return 0;
- X}
- X
- Xdbref db_write(FILE *f)
- X{
- X dbref i;
- X
- X for(i = 0; i < db_top; i++) {
- X fprintf(f, "#%d\n", i);
- X db_write_object(f, i);
- X }
- X fputs("***END OF DUMP***\n", f);
- X fflush(f);
- X return(db_top);
- X}
- X
- Xdbref parse_dbref(const char *s)
- X{
- X const char *p;
- X long x;
- X
- X x = atol(s);
- X if(x > 0) {
- X return x;
- X } else if(x == 0) {
- X /* check for 0 */
- X for(p = s; *p; p++) {
- X if(*p == '0') return 0;
- X if(!isspace(*p)) break;
- X }
- X }
- X
- X /* else x < 0 or s != 0 */
- X return NOTHING;
- X}
- X
- Xdbref getref(FILE *f)
- X{
- X static char buf[DB_MSGLEN];
- X
- X fgets(buf, sizeof(buf), f);
- X return(atol(buf));
- X}
- X
- Xstatic const char *getstring_noalloc(FILE *f)
- X{
- X static char buf[DB_MSGLEN];
- X char *p;
- X
- X fgets(buf, sizeof(buf), f);
- X for(p = buf; *p; p++) {
- X if(*p == '\n') {
- X *p = '\0';
- X break;
- X }
- X }
- X
- X return buf;
- X}
- X
- X#define getstring(x) alloc_string(getstring_noalloc(x))
- X
- X#ifdef COMPRESS
- Xextern const char *compress(const char *);
- X#define getstring_compress(x) alloc_string(compress(getstring_noalloc(x)));
- X#else
- X#define getstring_compress(x) getstring(x)
- X#endif /* COMPRESS */
- X
- Xstatic struct boolexp *negate_boolexp(struct boolexp *b)
- X{
- X struct boolexp *n;
- X
- X /* Obscure fact: !NOTHING == NOTHING in old-format databases! */
- X if(b == TRUE_BOOLEXP) return TRUE_BOOLEXP;
- X
- X n = (struct boolexp *) malloc(sizeof(struct boolexp));
- X n->type = BOOLEXP_NOT;
- X n->sub1 = b;
- X
- X return n;
- X}
- X
- Xstatic struct boolexp *getboolexp1(FILE *f)
- X{
- X struct boolexp *b;
- X int c;
- X
- X c = getc(f);
- X switch(c) {
- X case '\n':
- X ungetc(c, f);
- X return TRUE_BOOLEXP;
- X /* break; */
- X case EOF:
- X abort(); /* unexpected EOF in boolexp */
- X break;
- X case '(':
- X b = (struct boolexp *) malloc(sizeof(struct boolexp));
- X if((c = getc(f)) == '!') {
- X b->type = BOOLEXP_NOT;
- X b->sub1 = getboolexp1(f);
- X if(getc(f) != ')') goto error;
- X return b;
- X } else {
- X ungetc(c, f);
- X b->sub1 = getboolexp1(f);
- X switch(c = getc(f)) {
- X case AND_TOKEN:
- X b->type = BOOLEXP_AND;
- X break;
- X case OR_TOKEN:
- X b->type = BOOLEXP_OR;
- X break;
- X default:
- X goto error;
- X /* break */
- X }
- X b->sub2 = getboolexp1(f);
- X if(getc(f) != ')') goto error;
- X return b;
- X }
- X /* break; */
- X case '-':
- X /* obsolete NOTHING key */
- X /* eat it */
- X while((c = getc(f)) != '\n') if(c == EOF) abort(); /* unexp EOF */
- X ungetc(c, f);
- X return TRUE_BOOLEXP;
- X /* break */
- X default:
- X /* better be a dbref */
- X ungetc(c, f);
- X b = (struct boolexp *) malloc(sizeof(struct boolexp));
- X b->type = BOOLEXP_CONST;
- X b->thing = 0;
- X
- X /* NOTE possibly non-portable code */
- X /* Will need to be changed if putref/getref change */
- X while(isdigit(c = getc(f))) {
- X b->thing = b->thing * 10 + c - '0';
- X }
- X ungetc(c, f);
- X return b;
- X }
- X
- X error:
- X abort(); /* bomb out */
- X return TRUE_BOOLEXP;
- X}
- X
- Xstruct boolexp *getboolexp(FILE *f)
- X{
- X struct boolexp *b;
- X
- X b = getboolexp1(f);
- X if(getc(f) != '\n') abort(); /* parse error, we lose */
- X return b;
- X}
- X
- Xvoid free_boolexp(struct boolexp *b)
- X{
- X if(b != TRUE_BOOLEXP) {
- X switch(b->type) {
- X case BOOLEXP_AND:
- X case BOOLEXP_OR:
- X free_boolexp(b->sub1);
- X free_boolexp(b->sub2);
- X free((void *) b);
- X break;
- X case BOOLEXP_NOT:
- X free_boolexp(b->sub1);
- X free((void *) b);
- X break;
- X case BOOLEXP_CONST:
- X free((void *) b);
- X break;
- X }
- X }
- X}
- X
- Xvoid db_free(void)
- X{
- X dbref i;
- X struct object *o;
- X
- X if(db) {
- X for(i = 0; i < db_top; i++) {
- X o = &db[i];
- X if(o->name) free((void *) o->name);
- X if(o->description) free((void *) o->description);
- X if(o->succ_message) free((void *) o->succ_message);
- X if(o->fail_message) free((void *) o->fail_message);
- X if(o->ofail) free((void *) o->ofail);
- X if(o->osuccess) free((void *) o->osuccess);
- X if(o->password) free((void *) o->password);
- X if(o->key) free_boolexp(o->key);
- X }
- X free((void *) db);
- X db = 0;
- X db_top = 0;
- X }
- X}
- X
- Xdbref db_read(FILE *f)
- X{
- X dbref i;
- X struct object *o;
- X const char *end;
- X
- X#ifdef PLAYER_LIST
- X clear_players();
- X#endif
- X
- X db_free();
- X for(i = 0;; i++) {
- X switch(getc(f)) {
- X case '#':
- X /* another entry, yawn */
- X if(i != getref(f)) {
- X /* we blew it */
- X return -1;
- X }
- X /* make space */
- X db_grow(i+1);
- X
- X /* read it in */
- X o = db+i;
- X o->name = getstring(f);
- X o->description = getstring_compress(f);
- X o->location = getref(f);
- X o->contents = getref(f);
- X o->exits = getref(f);
- X o->next = getref(f);
- X o->key = getboolexp(f);
- X o->fail_message = getstring_compress(f);
- X o->succ_message = getstring_compress(f);
- X o->ofail = getstring_compress(f);
- X o->osuccess = getstring_compress(f);
- X o->owner = getref(f);
- X o->pennies = getref(f);
- X o->flags = getref(f);
- X o->password = getstring(f);
- X /* For downward compatibility with databases using the */
- X /* obsolete ANTILOCK flag. */
- X if(o->flags & ANTILOCK) {
- X o->key = negate_boolexp(o->key);
- X o->flags &= ~ANTILOCK;
- X }
- X#ifdef PLAYER_LIST
- X if(Typeof(i) == TYPE_PLAYER) {
- X add_player(i);
- X }
- X#endif PLAYER_LIST
- X break;
- X case '*':
- X end = getstring(f);
- X if(strcmp(end, "**END OF DUMP***")) {
- X free((void *) end);
- X return -1;
- X } else {
- X free((void *) end);
- X return db_top;
- X }
- X default:
- X return -1;
- X /* break; */
- X }
- X }
- X}
- X
- END_OF_FILE
- if test 9028 -ne `wc -c <'db.c'`; then
- echo shar: \"'db.c'\" unpacked with wrong size!
- fi
- # end of 'db.c'
- fi
- if test -f 'game.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'game.c'\"
- else
- echo shar: Extracting \"'game.c'\" \(14143 characters\)
- sed "s/^X//" >'game.c' <<'END_OF_FILE'
- X#include "copyright.h"
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <signal.h>
- X#include <sys/wait.h>
- X#include <time.h>
- X#include <stdarg.h>
- X
- X#include "db.h"
- X#include "config.h"
- X#include "interface.h"
- X#include "match.h"
- X#include "externs.h"
- X
- X/* declarations */
- Xstatic const char *dumpfile = 0;
- Xstatic int epoch = 0;
- Xstatic int alarm_triggered = 0;
- Xstatic int alarm_block = 0;
- X
- Xstatic void fork_and_dump(void);
- Xvoid dump_database(void);
- X
- Xvoid do_dump(dbref player)
- X{
- X if(Wizard(player)) {
- X alarm_triggered = 1;
- X notify(player, "Dumping...");
- X } else {
- X notify(player, "Sorry, you are in a no dumping zone.");
- X }
- X}
- X
- Xvoid do_shutdown(dbref player)
- X{
- X if(Wizard(player)) {
- X writelog("SHUTDOWN: by %s\n", unparse_object(player, player));
- X fflush(stderr);
- X shutdown_flag = 1;
- X } else {
- X notify(player, "Your delusions of grandeur have been duly noted.");
- X }
- X}
- X
- X/* should be void, but it's defined as int */
- Xstatic int alarm_handler(void)
- X{
- X alarm_triggered = 1;
- X if(!alarm_block) {
- X fork_and_dump();
- X }
- X return 0;
- X}
- X
- Xstatic void dump_database_internal(void)
- X{
- X char tmpfile[2048];
- X FILE *f;
- X
- X sprintf(tmpfile, "%s.#%d#", dumpfile, epoch - 1);
- X unlink(tmpfile); /* nuke our predecessor */
- X
- X sprintf(tmpfile, "%s.#%d#", dumpfile, epoch);
- X
- X if((f = fopen(tmpfile, "w")) != NULL) {
- X db_write(f);
- X fclose(f);
- X if(rename(tmpfile, dumpfile) < 0) perror(tmpfile);
- X } else {
- X perror(tmpfile);
- X }
- X}
- X
- Xvoid panic(const char *message)
- X{
- X char panicfile[2048];
- X FILE *f;
- X int i;
- X
- X writelog("PANIC: %s\n", message);
- X
- X /* turn off signals */
- X for(i = 0; i < NSIG; i++) {
- X signal(i, SIG_IGN);
- X }
- X
- X /* shut down interface */
- X emergency_shutdown();
- X
- X /* dump panic file */
- X sprintf(panicfile, "%s.PANIC", dumpfile);
- X if((f = fopen(panicfile, "w")) == NULL) {
- X perror("CANNOT OPEN PANIC FILE, YOU LOSE:");
- X#ifndef NODUMPCORE
- X signal(SIGILL, SIG_DFL);
- X abort();
- X#endif NODUMPCORE
- X _exit(135);
- X } else {
- X writelog("DUMPING: %s\n", panicfile);
- X db_write(f);
- X fclose(f);
- X writelog("DUMPING: %s (done)\n", panicfile);
- X#ifndef NODUMPCORE
- X signal(SIGILL, SIG_DFL);
- X abort();
- X#endif NODUMPCORE
- X _exit(136);
- X }
- X}
- X
- Xvoid writelog(const char *fmt, ...)
- X{
- X va_list list;
- X struct tm *tm;
- X long t;
- X char buffer[2048];
- X
- X va_start(list, fmt);
- X vsprintf(buffer, fmt, list);
- X t = time(NULL);
- X tm = localtime(&t);
- X fprintf(stderr, "%d/%02d %02d:%02d:%02d %s",
- X tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec,
- X buffer);
- X fflush(stderr);
- X va_end(list);
- X}
- X
- Xvoid dump_database(void)
- X{
- X epoch++;
- X
- X writelog("DUMPING: %s.#%d#\n", dumpfile, epoch);
- X dump_database_internal();
- X writelog("DUMPING: %s.#%d# (done)\n", dumpfile, epoch);
- X}
- X
- Xstatic void fork_and_dump(void)
- X{
- X int child;
- X
- X epoch++;
- X
- X writelog("CHECKPOINTING: %s.#%d#\n", dumpfile, epoch);
- X#ifdef USE_VFORK
- X child = vfork();
- X#else /* USE_VFORK */
- X child = fork();
- X#endif /* USE_VFORK */
- X if(child == 0) {
- X /* in the child */
- X close(0); /* get that file descriptor back */
- X dump_database_internal();
- X _exit(0); /* !!! */
- X } else if(child < 0) {
- X perror("fork_and_dump: fork()");
- X }
- X
- X /* in the parent */
- X /* reset alarm */
- X alarm_triggered = 0;
- X alarm(DUMP_INTERVAL);
- X}
- X
- Xstatic int reaper(void)
- X{
- X union wait stat;
- X
- X while(wait3(&stat, WNOHANG, 0) > 0);
- X return 0;
- X}
- X
- Xint init_game(const char *infile, const char *outfile)
- X{
- X FILE *f;
- X
- X if((f = fopen(infile, "r")) == NULL) return -1;
- X
- X /* ok, read it in */
- X writelog("LOADING: %s\n", infile);
- X if(db_read(f) < 0) return -1;
- X writelog("LOADING: %s (done)\n", infile);
- X
- X /* everything ok */
- X fclose(f);
- X
- X /* initialize random number generator */
- X srandom(getpid());
- X
- X /* set up dumper */
- X if(dumpfile) free((void *) dumpfile);
- X dumpfile = alloc_string(outfile);
- X signal(SIGALRM, (void (*)) alarm_handler);
- X signal(SIGHUP, (void (*)) alarm_handler);
- X signal(SIGCHLD, (void (*)) reaper);
- X alarm_triggered = 0;
- X alarm(DUMP_INTERVAL);
- X
- X return 0;
- X}
- X
- X/* use this only in process_command */
- X#define Matched(string) { if(!string_prefix((string), command)) goto bad; }
- X
- Xvoid process_command(dbref player, char *command)
- X{
- X char *arg1;
- X char *arg2;
- X char *q; /* utility */
- X char *p; /* utility */
- X
- X char *index(char *, char);
- X
- X if(command == 0) abort();
- X
- X /* robustify player */
- X if(player < 0 || player >= db_top || Typeof(player) != TYPE_PLAYER) {
- X writelog("process_command: bad player %d\n", player);
- X return;
- X }
- X
- X#ifdef LOG_COMMANDS
- X writelog("COMMAND from %s(%d) in %s(%d): %s\n",
- X db[player].name, player,
- X db[db[player].location].name, db[player].location,
- X command);
- X#endif /* LOG_COMMANDS */
- X
- X /* eat leading whitespace */
- X while(*command && isspace(*command)) command++;
- X
- X /* eat extra white space */
- X q = p = command;
- X while(*p) {
- X /* scan over word */
- X while(*p && !isspace(*p)) *q++ = *p++;
- X /* smash spaces */
- X while(*p && isspace(*++p));
- X if(*p) *q++ = ' '; /* add a space to separate next word */
- X }
- X /* terminate */
- X *q = '\0';
- X
- X /* block dump to prevent db inconsistencies from showing up */
- X alarm_block = 1;
- X
- X /* check for single-character commands */
- X if(*command == SAY_TOKEN) {
- X do_say(player, command+1, NULL);
- X } else if(*command == POSE_TOKEN) {
- X do_pose(player, command+1, NULL);
- X } else if(can_move(player, command)) {
- X /* command is an exact match for an exit */
- X do_move(player, command);
- X } else {
- X /* parse arguments */
- X
- X /* find arg1 */
- X /* move over command word */
- X for(arg1 = command; *arg1 && !isspace(*arg1); arg1++);
- X /* truncate command */
- X if(*arg1) *arg1++ = '\0';
- X
- X /* move over spaces */
- X while(*arg1 && isspace(*arg1)) arg1++;
- X
- X /* find end of arg1, start of arg2 */
- X for(arg2 = arg1; *arg2 && *arg2 != ARG_DELIMITER; arg2++);
- X
- X /* truncate arg1 */
- X for(p = arg2 - 1; p >= arg1 && isspace(*p); p--) *p = '\0';
- X
- X /* go past delimiter if present */
- X if(*arg2) *arg2++ = '\0';
- X while(*arg2 && isspace(*arg2)) arg2++;
- X
- X switch(command[0]) {
- X case '@':
- X switch(command[1]) {
- X case 'b':
- X case 'B':
- X switch (command[2]) {
- X case 'o':
- X case 'O':
- X switch (command[3]) {
- X case 'o':
- X case 'O': Matched("@boot");
- X do_boot(player, arg1);
- X break;
- X case 'b':
- X case 'B': if(string_compare(command, "@bobble")) goto bad;
- X do_bobble(player, arg1, arg2);
- X break;
- X default: goto bad;
- X }
- X break;
- X default: goto bad;
- X }
- X break;
- X case 'c':
- X case 'C':
- X /* chown, create */
- X switch(command[2]) {
- X case 'h':
- X case 'H':
- X Matched("@chown");
- X do_chown(player, arg1, arg2);
- X break;
- X#ifdef RECYCLE
- X case 'o':
- X case 'O':
- X Matched("@count");
- X do_count(player, arg1);
- X break;
- X#endif RECYCLE
- X case 'r':
- X case 'R':
- X Matched("@create");
- X do_create(player, arg1, atol(arg2));
- X break;
- X default:
- X goto bad;
- X }
- X break;
- X case 'd':
- X case 'D':
- X /* describe, dig, or dump */
- X switch(command[2]) {
- X case 'e':
- X case 'E':
- X Matched("@describe");
- X do_describe(player, arg1, arg2);
- X break;
- X case 'i':
- X case 'I':
- X Matched("@dig");
- X do_dig(player, arg1);
- X break;
- X case 'u':
- X case 'U':
- X Matched("@dump");
- X do_dump(player);
- X break;
- X default:
- X goto bad;
- X }
- X break;
- X case 'f':
- X /* fail, find, or force */
- X switch(command[2]) {
- X case 'a':
- X case 'A':
- X Matched("@fail");
- X do_fail(player, arg1, arg2);
- X break;
- X case 'i':
- X case 'I':
- X Matched("@find");
- X do_find(player, arg1);
- X break;
- X case 'o':
- X case 'O':
- X Matched("@force");
- X do_force(player, arg1, arg2);
- X break;
- X default:
- X goto bad;
- X }
- X break;
- X case 'l':
- X case 'L':
- X /* lock or link */
- X switch(command[2]) {
- X case 'i':
- X case 'I':
- X Matched("@link");
- X do_link(player, arg1, arg2);
- X break;
- X case 'o':
- X case 'O':
- X Matched("@lock");
- X do_lock(player, arg1, arg2);
- X break;
- X default:
- X goto bad;
- X }
- X break;
- X case 'm':
- X case 'M':
- X Matched("@mass_teleport");
- X do_mass_teleport(player, arg1);
- X break;
- X case 'n':
- X case 'N':
- X /* @name or @newpassword */
- X switch(command[2]) {
- X case 'a':
- X case 'A':
- X Matched("@name");
- X do_name(player, arg1, arg2);
- X break;
- X case 'e':
- X if(strcmp(command, "@newpassword")) goto bad;
- X do_newpassword(player, arg1, arg2);
- X break;
- X default:
- X goto bad;
- X }
- X break;
- X case 'o':
- X case 'O':
- X switch(command[2]) {
- X case 'f':
- X case 'F':
- X Matched("@ofail");
- X do_ofail(player, arg1, arg2);
- X break;
- X case 'p':
- X case 'P':
- X Matched("@open");
- X do_open(player, arg1, arg2);
- X break;
- X case 's':
- X case 'S':
- X Matched("@osuccess");
- X do_osuccess(player, arg1, arg2);
- X break;
- X case 'w':
- X case 'W':
- X Matched("@owned");
- X do_owned(player, arg1);
- X break;
- X default:
- X goto bad;
- X }
- X break;
- X case 'p':
- X case 'P':
- X switch(command[2]) {
- X case 'a':
- X case 'A':
- X Matched("@password");
- X do_password(player, arg1, arg2);
- X break;
- X#ifdef REGISTRATION
- X case 'c':
- X case 'C':
- X Matched("@pcreate");
- X do_pcreate(player, arg1, arg2);
- X break;
- X#endif REGISTRATION
- X default: goto bad;
- X }
- X break;
- X#ifdef RECYCLE
- X case 'r':
- X case 'R':
- X /* Recycle */
- X Matched("@recycle");
- X do_recycle(player, arg1);
- X break;
- X#endif RECYCLE
- X case 's':
- X case 'S':
- X /* set, shutdown, success */
- X switch(command[2]) {
- X case 'e':
- X case 'E':
- X Matched("@set");
- X do_set(player, arg1, arg2);
- X break;
- X case 'h':
- X if(strcmp(command, "@shutdown")) goto bad;
- X do_shutdown(player);
- X break;
- X case 't':
- X case 'T':
- X Matched("@stats");
- X do_stats(player, arg1);
- X break;
- X case 'u':
- X case 'U':
- X Matched("@success");
- X do_success(player, arg1, arg2);
- X break;
- X default:
- X goto bad;
- X }
- X break;
- X case 't':
- X case 'T':
- X switch(command[2]) {
- X case 'e':
- X case 'E':
- X Matched("@teleport");
- X do_teleport(player, arg1, arg2);
- X break;
- X case 'o':
- X case 'O':
- X if(string_compare(command, "@toad")) goto bad;
- X do_bobble(player, arg1, arg2);
- X break;
- X default:
- X goto bad;
- X }
- X break;
- X case 'u':
- X case 'U':
- X if(string_prefix(command, "@unli")) {
- X Matched("@unlink");
- X do_unlink(player, arg1);
- X } else if(string_prefix(command, "@unlo")) {
- X Matched("@unlock");
- X do_unlock(player, arg1);
- X } else if(string_prefix(command, "@unb")) {
- X Matched("@unbobble");
- X do_unbobble(player, arg1, arg2);
- X } else if(string_prefix(command, "@unt")) {
- X Matched("@untoad");
- X do_unbobble(player, arg1, arg2);
- X } else {
- X goto bad;
- X }
- X break;
- X case 'w':
- X if(strcmp(command, "@wall")) goto bad;
- X do_wall(player, arg1, arg2);
- X break;
- X default:
- X goto bad;
- X }
- X break;
- X case 'd':
- X case 'D':
- X Matched("drop");
- X do_drop(player, arg1);
- X break;
- X case 'e':
- X case 'E':
- X if (command[1] == 'x' || command[1] == 'X') {
- X Matched("examine");
- X do_examine(player, arg1);
- X break;
- X } else {
- X goto bad;
- X }
- X case 'g':
- X case 'G':
- X /* get, give, go, or gripe */
- X switch(command[1]) {
- X case 'e':
- X case 'E':
- X Matched("get");
- X do_get(player, arg1);
- X break;
- X case 'i':
- X case 'I':
- X Matched("give");
- X do_give(player, arg1, atol(arg2));
- X break;
- X case 'o':
- X case 'O':
- X Matched("goto");
- X do_move(player, arg1);
- X break;
- X case 'r':
- X case 'R':
- X Matched("gripe");
- X do_gripe(player, arg1, arg2);
- X break;
- X default:
- X goto bad;
- X }
- X break;
- X case 'h':
- X case 'H':
- X Matched("help");
- X do_help(player);
- X break;
- X case 'i':
- X case 'I':
- X Matched("inventory");
- X do_inventory(player);
- X break;
- X case 'k':
- X case 'K':
- X Matched("kill");
- X do_kill(player, arg1, atol(arg2));
- X break;
- X case 'l':
- X case 'L':
- X Matched("look");
- X do_look_at(player, arg1);
- X break;
- X case 'm':
- X case 'M':
- X Matched("move");
- X do_move(player, arg1);
- X break;
- X case 'n':
- X case 'N':
- X /* news */
- X if(string_compare(command, "news")) goto bad;
- X do_news(player);
- X break;
- X case 'p':
- X case 'P':
- X Matched("page");
- X do_page(player, arg1, arg2);
- X break;
- X case 'r':
- X case 'R':
- X switch(command[1]) {
- X case 'e':
- X case 'E':
- X Matched("read"); /* undocumented alias for look at */
- X do_look_at(player, arg1);
- X break;
- X case 'o':
- X case 'O':
- X Matched("rob");
- X do_rob(player, arg1);
- X break;
- X default:
- X goto bad;
- X }
- X break;
- X case 's':
- X case 'S':
- X /* say, "score" */
- X switch(command[1]) {
- X case 'a':
- X case 'A':
- X Matched("say");
- X do_say(player, arg1, arg2);
- X break;
- X case 'c':
- X case 'C':
- X Matched("score");
- X do_score(player);
- X break;
- X default:
- X goto bad;
- X }
- X break;
- X case 't':
- X case 'T':
- X switch(command[1]) {
- X case 'a':
- X case 'A':
- X Matched("take");
- X do_get(player, arg1);
- X break;
- X case 'h':
- X case 'H':
- X Matched("throw");
- X do_drop(player, arg1);
- X break;
- X default:
- X goto bad;
- X }
- X break;
- X case 'w':
- X case 'W':
- X Matched("whisper");
- X do_whisper(player, arg1, arg2);
- X break;
- X default:
- X bad:
- X notify(player, "Huh? (Type \"help\" for help.)");
- X#ifdef LOG_FAILED_COMMANDS
- X if(!controls(player, db[player].location)) {
- X writelog("HUH from %s(%d) in %s(%d)[%s]: %s %s\n",
- X db[player].name, player,
- X db[db[player].location].name,
- X db[player].location,
- X db[db[db[player].location].owner].name,
- X command,
- X reconstruct_message(arg1, arg2));
- X }
- X#endif /* LOG_FAILED_COMMANDS */
- X break;
- X }
- X }
- X
- X /* unblock alarms */
- X alarm_block = 0;
- X if(alarm_triggered) {
- X fork_and_dump();
- X }
- X}
- X
- X#undef Matched
- END_OF_FILE
- if test 14143 -ne `wc -c <'game.c'`; then
- echo shar: \"'game.c'\" unpacked with wrong size!
- fi
- # end of 'game.c'
- fi
- if test -f 'restart-cmu' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'restart-cmu'\"
- else
- echo shar: Extracting \"'restart-cmu'\" \(576 characters\)
- sed "s/^X//" >'restart-cmu' <<'END_OF_FILE'
- X#!/bin/csh -f
- X#
- X# This script assumes you have the following structure:
- X#
- X# $HOME/bin executable MUD programs
- X# $HOME/lib database files, daily logs
- X# $HOME/src source code for netmud
- X#
- X
- Xcd /usr/tinymud/lib
- Xmv tinymud.db tinymud.db.old
- Xif(-r tinymud.db.new) then
- X mv tinymud.db.new tinymud.db
- Xelse
- X cp tinymud.db.old tinymud.db
- Xendif
- X
- X# Use netmud instead of netmud.conc if you don't want the port concentrator
- Xcp ../bin/netmud.conc netmud.exe
- Xcp ../bin/concentrate concentrate
- X
- Xecho RESTARTED AT `date` >> tinymud.log
- X./netmud.exe tinymud.db tinymud.db.new >>& tinymud.log &
- END_OF_FILE
- if test 576 -ne `wc -c <'restart-cmu'`; then
- echo shar: \"'restart-cmu'\" unpacked with wrong size!
- fi
- chmod +x 'restart-cmu'
- # end of 'restart-cmu'
- fi
- if test -f 'tinymud.tex' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'tinymud.tex'\"
- else
- echo shar: Extracting \"'tinymud.tex'\" \(28102 characters\)
- sed "s/^X//" >'tinymud.tex' <<'END_OF_FILE'
- X\documentstyle[11pt,titlepage,makeidx,ragright]{article}
- X
- X\newcommand{\bs}{\char '134} % backslash character for \tt font
- X\newcommand{\ub}{\char '137} % underbar character for \tt font
- X\newcommand{\ua}{\char '136} % up arrow character for \tt font
- X\newcommand{\qt}{\char '175} % quotes character for \tt font
- X\newcommand{\tl}{\char '176} % tilde character for \tt font
- X\newcommand{\sh}{\char '043} % sharp character for \tt font
- X
- X\newcommand{\tinymud}{{\small Tiny}{MUD}}
- X\newcommand{\type}[1]{{\tt #1\/}}
- X
- X\newenvironment{simple}{\begin{list}%
- X{\relax}%
- X{\setlength{\labelwidth}{0pt}%
- X \setlength{\labelsep}{0pt}%
- X \setlength{\leftmargin}{0pt}%
- X \setlength{\listparindent}{0pt}}}%
- X{\end{list}}
- X
- X%\newenvironment{simple}{\begin{trivlist}}{\end{trivlist}}
- X
- X%\newlength{\boxwidth}
- X%\setlength{\boxwidth}{\textwidth}
- X%\addtolength{\boxwidth}{-7pt}
- X
- X\newlength{\rulewidth}
- X\setlength{\rulewidth}{\textwidth}
- X%\divide\rulewidth by 3
- X
- X\newcommand{\dorule}{\begin{center}
- X\rule{\rulewidth}{1pt}
- X\end{center}}
- X
- X\makeindex
- X
- X\title{{\bf A brief guide to {\large\bf Tiny}MUD}}
- X
- X\author{Jennifer Stone (aka Chrysalis) \\
- X{\tt jennifer@uokmax.ecn.uoknor.edu}
- X\and
- XRusty C. Wright \\
- X{\tt rusty@garnet.berkeley.edu}}
- X
- X\begin{document}
- X
- X% uncomment the commented lines if you want a more formal document
- X% with a separate title page and table of contents.
- X
- X\ragright
- X
- X\pagenumbering{roman}
- X
- X\maketitle
- X
- X\tableofcontents
- X\clearpage
- X
- X\pagenumbering{arabic}
- X
- XMuch of this is from the {\tinymud} source code and the {\tt small.db}
- Xexample.
- X
- X\section{Ordinary commands}
- X\label{sec:ordinary-commands}
- X
- X\begin{simple}
- X
- X\item[]
- X\begin{flushleft}
- X{\tt drop} $<${\em object\/}$>$ \\
- X{\tt throw} $<${\em object\/}$>$
- X\index{drop@\type{drop}}
- X\index{throw@\type{throw}}
- X\end{flushleft}
- XDrops the specified object. $<${\em object\/}$>$ can be either a
- Xthing or exit.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt examine} $<${\em name\/}$>$ \\
- X{\tt examine} {\tt \#}$<${\em number\/}$>$
- X\index{examine@\type{examine}}
- X\end{flushleft}
- XPrints a detailed description of object specified by $<${\em
- Xname\/}$>$ or by $<${\em number\/}$>$ giving name, description, owner,
- Xkeys, pennies, failure message, success message, others failure
- Xmessage, others success message, and exits. The location will also be
- Xdisplayed if you control the object's location (that is, if it's not
- Xbeing carried by someone else or in a room you don't control).
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt get} $<${\em object\/}$>$ \\
- X{\tt take} $<${\em object\/}$>$
- X\index{get@\type{get}}
- X\index{take@\type{take}}
- X\end{flushleft}
- XGets the specified object. $<${\em object\/}$>$ can be either a thing
- Xor exit.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt give} $<${\em player\/}$>$ \verb|=| $<${\em amount\/}$>$
- X\index{give@\type{give}}
- X\end{flushleft}
- XGives $<${\em player\/}$>$ the specified number of pennies.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt go} $<${\em direction\/}$>$ \\
- X{\tt go home} \\
- X{\tt move} $<${\em direction\/}$>$ \\
- X{\tt move home}
- X\index{go@\type{go}}
- X\index{move@\type{move}}
- X\index{home@\type{home}}
- X\end{flushleft}
- X
- XMoves in the specified direction. {\tt go home} is a special command
- Xthat returns you to your home (initially Limbo). If the direction is
- Xfully specified, the {\tt go} may be omitted.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt gripe} $<${\em message\/}$>$
- X\index{gripe@\type{gripe}}
- X\end{flushleft}
- XSends $<${\em message\/}$>$ to the system maintainer.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt help}
- X\index{help@\type{help}}
- X\end{flushleft}
- XPrints a short help message.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt inventory}
- X\index{inventory@\type{inventory}}
- X\end{flushleft}
- XLists what you are carrying.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt kill} $<${\em player\/}$>$ $[$ \verb|=| $<${\em cost\/}$>$ $]$
- X\index{kill@\type{kill}}
- X\end{flushleft}
- XKills the specified player. Killing costs either $<${\em cost\/}$>$
- Xpennies or 10 pennies, whichever is greater. The probability of
- Xsuccess is proportional to the cost.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt look} $<${\em object\/}$>$ \\
- X{\tt read} $<${\em object\/}$>$
- X\index{look@\type{look}}
- X\index{read@\type{read}}
- X\end{flushleft}
- X$<${\em object\/}$>$ can be a room, thing, player, or direction. Prints
- Xa description of $<${\em object\/}$>$.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt page} $<${\em player\/}$>$
- X\index{page@\type{page}}
- X\end{flushleft}
- XUsed to inform an active player that you are looking for them. The
- Xtargeted player will get a message telling them your name and
- Xlocation.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt rob} $<${\em player\/}$>$
- X\index{rob@\type{rob}}
- X\end{flushleft}
- XAttempt to steal a penny from $<${\em player\/}$>$.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt say} $<${\em message\/}$>$ \\
- X\verb|"|$<${\em message\/}$>$ \\
- X\verb|:|$<${\em message\/}$>$
- X\index{say@\type{say}}
- X\index{""@\type{""}}
- X\index{:@\type{:}}
- X\end{flushleft}
- XThe first two forms display the $<${\em message\/}$>$ with the
- Xnotification that you said it. For example, if your player's name is
- XBetty the other players in the same room will see
- X\begin{flushleft}
- X{\tt Betty says} ``$<${\em message\/}$>$''
- X\end{flushleft}
- XThe third form {\sl poses} the message, preceded by your name, with no
- Xquotes, as in
- X\begin{flushleft}
- X{\tt Betty} $<${\em message\/}$>$
- X\end{flushleft}
- XFor both the second and third forms, do not put a space after
- Xthe double quotes or colon as it will be included in the message.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt score}
- X\index{score@\type{score}}
- X\end{flushleft}
- XPrints how many pennies you have.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt whisper} $<${\em player\/}$>$ \verb|=| $<${\em message\/}$>$
- X\index{whisper@\type{whisper}}
- X\end{flushleft}
- X$<${\em player\/}$>$ is presented with $<${\em message\/}$>$ saying
- Xthat you whispered it. The other players only see the message
- X\begin{flushleft}
- X{\tt Betty whispers something to} $<${\em player\/}$>$.
- X\end{flushleft}
- X
- X\end{simple}
- X
- X\section{Commands for modifying the dungeon}
- X\label{sec:commands-for-modifying-the-dungeon}
- X
- X\begin{simple}
- X
- X\item[]
- X\begin{flushleft}
- X{\tt @create\/} $<${\em name\/}$>$ $[$ \verb|=| $<${\em cost\/}$>$ $]$
- X\index{create@\type{"@create}}
- X\end{flushleft}
- XCreates a thing with the specified name. Creation costs either
- X$<${\em cost\/}$>$ pennies or 10 pennies, whichever is greater. The
- Xvalue of a thing is proportional to its cost.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt @describe} $<${\em object\/}$>$ \verb|=| $<${\em description\/}$>$
- X\index{describe@\type{"@describe}}
- X\end{flushleft}
- X$<${\em object\/}$>$ can be a room, thing, player, or direction. Sets
- Xthe description a player sees when they use the command {\tt look}
- X$<${\em object\/}$>$. If $<${\em object\/}$>$ is {\tt
- Xhere}\index{here@\type{here}} it sets the description for the current
- Xroom that is displayed when the room is entered. If $<${\em
- Xobject\/}$>$ is {\tt me}\index{me@\type{me}} it sets the description for
- Xyour character.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt @dig} $<${\em name\/}$>$
- X\index{dig@\type{"@dig}}
- X\end{flushleft}
- XCreates a new room with the specified name, and prints the room's
- Xnumber.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt @fail} $<${\em object\/}$>$ $[$ \verb|=| $<${\em message\/}$>$
- X$]$
- X\index{fail@\type{"@fail}}
- X\end{flushleft}
- XWithout a message argument, clears the failure message on $<${\em
- Xobject\/}$>$, otherwise sets it. The failure message is printed when
- Xa player unsuccessfully attempts to use the object.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt @find} $<${\em name\/}$>$
- X\index{find@\type{"@find}}
- X\end{flushleft}
- XPrints the name and object number of every room, thing, or player that
- Xyou control whose name matches $<${\em name\/}$>$. Because the {\tt
- X@find} command is computationally expensive, there is a small charge
- Xfor using it.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt @link} $<${\em direction\/}$>$ \verb|=| $<${\em room number\/}$>$ \\
- X{\tt @link} $<${\em thing\/}$>$ \verb|=| $<${\em room number\/}$>$ \\
- X{\tt @link} $<${\em room\/}$>$ \verb|=| $<${\em room number\/}$>$
- X\index{link@\type{"@link}}
- X\end{flushleft}
- XIn the first form links the exit specified by $<${\em direction\/}$>$
- Xto the room specified by $<${\em room number\/}$>$. The exit must be
- Xunlinked, and you must own the target room if its
- X\verb|link_ok|\index{linkok@\verb,link_ok,} attribute is not set. If
- Xyou don't already own the exit its ownership is transferred to you.
- XThe second form sets the home for $<${\em thing\/}$>$\index{home}. If
- X$<${\em thing\/}$>$ is {\tt me}\index{me@\type{me}} it sets your home.
- XThe third form sets the dropto; see section~\ref{sec:droptos} for an
- Xexplanation of dropto's.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt @lock} $<${\em object\/}$>$ \verb|=| $<${\em key\/}$>$
- X\index{lock@\type{"@lock}}
- X\end{flushleft}
- XSets a key (another object) for an object. If $<${\em key\/}$>$
- Xstarts with \verb|*| then it must be a player's name. $<${\em
- Xkey\/}$>$ can contain the Boolean operators \verb|!| (not or
- Xnegation), \verb|&| (and), and \verb:|: (or), and use parentheses for
- Xgrouping.
- X
- XIn order to use $<${\em object\/}$>$ you must satisfy the requirements
- Xof $<${\em key\/}$>$. In the simplest case you must simply have
- X$<${\em key\/}$>$. If $<${\em key\/}$>$ is preceded by \verb|!| then
- Xyou must not have $<${\em key\/}$>$ in order to use $<${\em
- Xobject\/}$>$. See section~\ref{sec:lock-key-boolean-examples} for
- Xmore complicated examples.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt @name} $<${\em object\/}$>$ \verb|=| $<${\em name\/}$>$ \\
- X{\tt @name} $<${\em player\/}$>$ \verb|=| $<${\em name\/}$>$ $<${\em
- Xpassword\/}$>$
- X\index{name@\type{"@name}}
- X\end{flushleft}
- XChanges the name of the specified object. This can also be used to
- Xspecify a new direction list for an exit (see for example {\tt
- X@open\/}). For a player, it requires the player's password.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt @ofail} $<${\em object\/}$>$ $[$ \verb|=| $<${\em message\/}$>$
- X$]$
- X\index{ofail@\type{"@ofail}}
- X\end{flushleft}
- XWithout a message argument, clears the others failure message on
- X$<${\em object\/}$>$, otherwise sets it. The others failure message,
- Xprefixed by the player's name, is shown to others when the player
- Xfails to use $<${\em object\/}$>$.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt @open} $<${\em direction\/}$>$ $[$ {\tt;} $<${\em other-dir\/}$>$
- X$]*$ $[$ {\tt =} $<${\em destination\/}$>$ $]$
- X\index{open@\type{"@open}}
- X\end{flushleft}
- XCreates an unlinked exit in the specified direction(s). You can also
- Xspecify an exit to link the exit to. Once created, you (or any other
- Xplayer) may use the {\tt @link} command to specify the room to which
- Xthe exit leads. See also {\tt @name}.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt @osuccess} $<${\em object\/}$>$ $[$ \verb|=| $<${\em
- Xmessage\/}$>$ $]$
- X\index{osuccess@\type{"@osuccess}}
- X\end{flushleft}
- XWithout a message argument, clears the others success message on
- X$<${\em object\/}$>$, otherwise sets it. The others success message,
- Xprefixed by the player's name, is shown to others when the player
- Xsuccessfully uses $<${\em object\/}$>$.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt @password} $<${\em old\/}$>$ \verb|=| $<${\em new\/}$>$
- X\index{password@\type{"@password}}
- X\end{flushleft}
- XSets a new password; you must specify your old password to verify your
- Xidentity.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt @set} $<${\em object\/}$>$ \verb|=| $<${\em flag\/}$>$ \\
- X{\tt @set} $<${\em object\/}$>$ \verb|=| {\tt !}$<${\em flag\/}$>$
- X\index{set@\type{"@set}}
- X\end{flushleft}
- XSets (first form) or resets (second form) $<${\em flag\/}$>$ on
- X$<${\em object\/}$>$. The current flags are \verb|dark|,
- X\verb|link_ok|, \verb|sticky|, \verb|temple|, and \verb|wizard|.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt @success} $<${\em object\/}$>$ \verb|=| $<${\em message\/}$>$
- X\index{success@\type{"@success}}
- X\end{flushleft}
- XWithout a message argument, clears the success message on $<${\em
- Xobject\/}$>$, otherwise sets it. The success message is printed when
- Xa player successfully uses $<${\em object\/}$>$. Without $<${\em
- Xmessage}$>$ it clears the success message.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt @teleport} $<${\em object\/}$>$ {\tt =} $<${\em destination\/}$>$
- X\index{teleport@\type{"@teleport}}
- X\end{flushleft}
- XTeleports the object to the specified destination. You must either
- Xcontrol the object or it's current location, and you must be able to
- Xlink to the destination. You can only teleport objects from room to
- Xroom, not into or out of someone's hand.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt @unlink} $<${\em direction\/}$>$
- X\index{unlink@\type{"@unlink}}
- X\end{flushleft}
- XRemoves the link on the exit in the specified $<${\em direction\/}$>$.
- XYou must own the exit. The exit may then be relinked by any player
- Xusing the {\tt @link} command and ownership of the exit transfers to
- Xthat player.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt @unlock} $<${\em object\/}$>$
- X\index{unlock@\type{"@unlock}}
- X\end{flushleft}
- XRemoves the lock on an object.
- X
- X\end{simple}
- X
- X\section{Miscellaneous commands}
- X\label{sec:miscellaneous-commands}
- X
- X\begin{simple}
- X
- X\item[]
- X\begin{flushleft}
- X{\tt @stats}
- X\index{stats@\type{"@stats}}
- XShows current total of players, rooms, objects, exits.
- X\end{flushleft}
- X
- X\end{simple}
- X
- X\section{Money}
- X\label{sec:money}
- X
- XSome actions have an associated cost:
- X\begin{center}
- X\begin{tabular}{|l|p{4in}|}
- X\hline
- X\multicolumn{1}{|c|}{{\bf Action}} &
- X\multicolumn{1}{c|}{{\bf Cost}} \\
- X\hline
- X\hline
- X\hline
- X{\tt kill} & 10 pennies or more \\
- X\hline
- X{\tt page} & 1 penny \\
- X\hline
- X{\tt @open} & 1 penny \\
- X\hline
- X{\tt @dig} & 10 pennies \\
- X\hline
- X{\tt @create} & 10 pennies (or more) \\
- X\hline
- X{\tt @link} & 1 penny, plus 1 penny to the previous owner if you
- Xdidn't already own the exit. \\
- X\hline
- X\end{tabular}
- X\index{kill@\type{kill}}
- X\index{page@\type{page}}
- X\index{open@\type{"@open}}
- X\index{dig@\type{"@dig}}
- X\index{create@\type{"@create}}
- X\index{link@\type{"@link}}
- X\end{center}
- X
- XYou get money by finding pennies, getting killed, having someone give
- Xyou money, or by sacrificing a thing. The sacrifice value of a thing
- Xis $(\mbox{\rm cost of the thing} / 5 ) - 1$.
- X
- X\section{TinyMUD concepts}
- X\label{sec:tinymud-concepts}
- X
- XAn {\em object} is either a player, room, thing, or exit.
- X
- XIn addition to the commands listed above there are some built in words
- Xin {\tinymud}; {\tt me}\index{me@\type{me}} and {\tt
- Xhere}\index{here@\type{here}}. {\tt me} refers to your character or
- Xplayer, and {\tt here} refers to the room you are in. For example,
- Xyou can use the \verb|@describe| command to give yourself a
- Xdescription; as another example, in order to prevent yourself from
- Xbeing robbed use {\tt @lock me = me\/}.
- X
- X\subsection{Success and the lack thereof}
- X\label{sec:success-and-the-lack-thereof}
- X
- XWhen you can {\tt take} a thing, use an exit, or rob a player you are
- Xsuccessfull in using that object. The converse is true for failure.
- XThe {\tt @success\/}, {\tt @osuccess\/}, {\tt @fail\/}, and {\tt
- X@ofail} commands set the success and failure messages on objects.%
- X\index{success@\type{"@success}}%
- X\index{osuccess@\type{"@osuccess}}%
- X\index{fail@\type{"@fail}}%
- X\index{ofail@\type{"@ofail}}
- X
- X\subsection{Object strings}
- X\label{sec:object-strings}
- X
- XEvery object has six strings:
- X\begin{enumerate}
- X\item
- XName. This is what you use with {\tt drop\/}, {\tt examine\/}, {\tt
- Xget\/}, and so on. You can also use the object's number (for example,
- Xwhen two objects have the same name).
- X
- X\item
- XDescription. This is what is given when you use the {\tt look}
- Xcommand.
- X
- X\item
- XSuccess message. This is what you see when you successfully use the
- Xobject.
- X
- X\item
- XOthers success message. This is what the other players see when you
- Xsuccessfully use the object.
- X
- X\item
- XFailure message. This is what you see when you fail to use an object.
- X
- X\item
- XOthers failure message. This is what the other players see when you
- Xfail to use an object.
- X\end{enumerate}
- XThe maximum length of each string is 512 characters.
- X
- X\subsection{Object properties}
- X\label{sec:object-properties}
- X
- XAs listed in the \verb|@set| command, objects can have any of the
- Xfollowing properties:
- X\begin{description}
- X\item[{\tt dark}]
- X\index{dark@\type{dark}}
- XWhen a room has its {\tt dark} flag set you can't see things in it
- Xwith the {\tt look} command. When a thing or player has its {\tt
- Xdark} flag set it can't be seen. Only a wizard can set the {\tt dark}
- Xflag on a thing or player. Setting the {\tt dark} flag on exits
- Xcurrently has no effect.
- X
- X\item[{\tt link{\ub}ok}]
- X\index{linkok@\verb,link_ok,}
- XYou can link to a room if you control it, or if the room has its
- X\verb|link_ok| flag set. Being able to link to a room means that you
- Xcan set the homes\index{home} of things (or yourself) to that room,
- Xand you can set the destination of exits to that room. See also the
- X{\tt @link} command for additional information on linking and
- Xsection~\ref{sec:droptos} for droptos. Setting the
- X\verb|link_ok| flag on players, things, and exits currently has no
- Xeffect.
- X
- X\item[{\tt sticky}]
- X\index{sticky@\type{sticky}}
- XWhen an object that has its {\tt sticky} flag set is dropped it
- Ximmediately goes home. When a room has its {\tt sticky} flag set its
- Xdropto is delayed until the last person leaves the room. Setting the
- X{\tt sticky} flag on players and exits currently has no effect.
- X
- X\item[{\tt temple}]
- X\index{temple@\type{temple}}
- XWhen a room has its {\tt temple} flag set you can sacrifice things
- Xthere and receive pennies for your sacrifices. (See
- Xsection~\ref{sec:money} for how many pennies you receive for your
- Xsacrifices.) Only a wizard can set this flag. Setting this flag on
- Xplayers, things, and exits currently has no effect.
- X
- X\item[{\tt wizard}]
- X\index{wizard@\type{wizard}}
- XWhen a player has its {\tt wizard} flag set they are a wizard. Only a
- Xwizard can set this flag. Setting this flag on things, rooms, and
- Xexits currently has no effect.
- X
- X\end{description}
- X
- XThe flags {\tt player\/}, {\tt room\/}, and {\tt exit} are set
- Xautomatically when a player, room, or exit is created. They cannot be
- Xsubsequently unset or set with the \verb|@set| command.
- X
- X\subsection{Control}
- X\label{sec:control}
- X
- XThere are three rules for determining control:
- X\begin{enumerate}
- X\item
- XYou can control anything you own.
- X\item
- XA wizard can control anything.
- X\item\label{item:unlinked-exit}
- XAnybody can control an unlinked exit (even if it is locked).
- X\end{enumerate}
- XBuilders should watch out for item~\ref{item:unlinked-exit}.
- X
- X\subsection{Dropto's}
- X\label{sec:droptos}
- X
- X\index{droptos}
- XWhen the {\tt @link} command is used on a room, it sets a dropto
- Xlocation for that room. Any thing dropped in the room (if it is not
- X{\tt sticky\/}; see above) will go to that location. If the room has
- Xits {\tt sticky\/} flag set the effect of the dropto will be delayed
- Xuntil the last player leaves the room. The special location {\tt
- Xhome} may be used as a dropto, as in {\tt @link here = home\/}; in
- Xthat case things dropped in the room will go to their
- Xhomes\index{home@\type{home}}. To remove the dropto on a room go into
- Xthat room and use {\tt @unlink here\/}\index{here@\type{here}}.
- X
- X\subsection{Homes}
- X\label{sec:homes}
- X
- X\index{home}
- XEvery thing or player has a home. For things, this is the location
- Xthe thing returns to when sacrificed, when a player carrying it goes
- Xhome, or when (if its {\tt sticky\/} flag is set) it is dropped. For
- Xplayers, this is where the player goes when they issue the {\tt home}
- Xcommand. Homes may be set using the {\tt @link} command; for example,
- X{\tt @link donut =} $<${\em room-number\/}$>$ or {\tt @link me =}
- X$<${\em room-number\/}$>$\index{me@\type{me}}. Exits may also be
- Xlinked to the special location {\tt home\/}; for example, {\tt @link
- Xnorth = home\/}\index{home@\type{home}}.
- X
- X\subsection{Recycling}
- X\label{sec:recycling}
- X
- XNothing can be destroyed in {\tinymud}, but it is possible to recycle
- Xjust about anything. The {\tt @name} command can be used to rename
- Xobjects, making it easy to turn a silk purse into a sow's ear or vice
- Xversa. Extra exits can be unlinked and picked up by their owner using
- Xthe {\tt get} command, and dropped like things using the {\tt drop}
- Xcommand in any room controlled by the dropper.
- X
- X\subsection{Being killed}
- X\label{sec:being-killed}
- X
- XWhen you are killed you return to your home and any items you were
- Xcarrying return to their homes. As a consolation you receive 50
- Xpennies from the {\tinymud} Total Life Indemnity insurance
- Xcompany.
- X
- X\section{Examples}
- X\label{sec:examples}
- X
- XHere we present examples to demonstrate some of the features of
- X{\tinymud}.
- X
- X\subsection{Success and failure messages}
- X\label{sec:success-and-failure-messages}
- X
- XSuccess and failure messages are fairly straightforward. Just
- Xremember that for the messages set with {\tt
- X@osuccess}\index{osuccess@\type{"@osuccess}} and {\tt
- X@ofail}\index{ofail@\type{"@ofail}} the player's name is prefixed onto
- Xthe message when it is printed, while the messages set with {\tt
- X@success}\index{success@\type{"@success}} and {\tt
- X@fail}\index{fail@\type{"@fail}} are printed as-is.
- X
- XPreviously we saw that you can use {\tt say}, \verb|"|, and \verb|:|
- Xto display messages. An older method for posing non sequiturs is to
- Xset the others success message on yourself and then rob yourself. For
- Xexample, if your character is Betty and you do
- X\index{say@\type{say}}
- X\index{""@\type{""}}
- X\index{:@\type{:}}
- X\begin{verbatim}
- X@osuccess me = starts picking her nose.
- Xrob me
- X\end{verbatim}
- Xon your screen you'll see
- X\begin{verbatim}
- XYou stole a penny.
- XBetty stole one of your pennies!
- X\end{verbatim}
- Xwhile the other players will see
- X\begin{verbatim}
- XBetty starts picking her nose.
- X\end{verbatim}
- XAn easier way to accomplish this is to simply do
- X\begin{verbatim}
- X:starts picking her nose.
- X\end{verbatim}
- Xthen both you and the others see
- X\begin{verbatim}
- XBetty starts picking her nose.
- X\end{verbatim}
- XWhen using \verb|"| and \verb|:| don't follow them with a space
- Xbecause it will be included in the output; put the message right up
- Xagainst the quotes or colon.
- X
- X\subsection{Making your home}
- X\label{sec:making-your-home}
- X
- X\index{home}
- XThe minimal steps for making your home are
- X\begin{enumerate}
- X\item
- XMake the room for your home with the {\tt @dig} command. Write down
- Xthe room number in case the following step takes a long time.
- X
- X\item
- X\label{item:exit}
- XMake or acquire an exit. In order to use the {\tt @open} command you
- Xmust own the room that you are doing the {\tt @open} in. The
- Xalternative is to find a room with an exit that isn't linked and use
- Xit.
- X
- X\item
- XMake a link to your home. Once you've made or found an unlinked exit
- Xsimply use the {\tt @link} command to link the exit to your room.
- X
- X\item
- X\label{item:exit-room}
- XFind a room to which you can make a link in order to have an exit from
- Xyour room (this is a room with the \verb|link_ok| flag set). For the
- Xsake of example we'll pretend the number of this room is 711; we'll be
- Xusing it in step~\ref{item:exit-link}. Without this you'd be able to
- Xgo to your home but you wouldn't have any way to get out of it.
- X
- X\item
- XSet the link from you to your home. Go into your room and do
- X\index{here@\type{here}}
- X\index{link@\type{"@link}}
- X\begin{verbatim}
- X@link me = here
- X\end{verbatim}
- X
- X\item
- X\label{item:exit-link}
- XMake the exit and link it to the destination
- X\begin{verbatim}
- X@open out
- X@link out = #711
- X\end{verbatim}
- X(The \verb|#| isn't mandatory.)
- X\end{enumerate}
- X
- XOf course there are probably various details that you would want to
- Xtake care of in addition to the above steps. For example, if you're
- Xantisocial and want to prevent other people from using your home room
- Xyou'd do
- X\index{lock@\type{"@lock}}
- X\begin{verbatim}
- X@lock down = me
- X\end{verbatim}
- Xassuming that {\tt down} is the exit you made in step~\ref{item:exit}.
- XAlong a similar vein you might not want other people linking to your
- Xroom in which case you'd turn off the \verb|link_ok| flag on your
- Xroom. You might also set the description of your home room. If you
- Xown the exit you could also set the success, others success, fail, and
- Xothers fail messages on the exit to your home. Without the
- Xdescriptions places and things are boring and uninteresting.
- X
- X\subsection{Lock key boolean examples}
- X\label{sec:lock-key-boolean-examples}
- X
- XWhen using the {\tt @lock} command the key is either another object or
- Xsome boolean combination of other objects. If the key starts with a
- X\verb|*| then that object must be a player.
- X
- XFor example, if a room has a direction {\tt out} and you want to
- Xprevent players from carrying the object {\tt xyz} when they go out,
- Xyou would use
- X\begin{verbatim}
- X@lock out = !xyz
- X\end{verbatim}
- Xor if you want to prevent the player Julia from using the {\tt out}
- Xexit you would use
- X\begin{verbatim}
- X@lock out = !*Julia
- X\end{verbatim}
- XIf you want to prevent only Julia from going out with {\tt xyz} you
- Xwould use
- X\begin{verbatim}
- X@lock out = ( *Julia & !xyz )
- X\end{verbatim}
- X
- X\subsection{Ersatz commands}
- X\label{sec:ersatz-commands}
- X
- XYou can make new commands by making an exit and then locking it to
- Xsomething impossible to have and then assigning the failure and others
- Xfailure messages to it. For example, assume the following commands
- Xhave been used
- X\begin{verbatim}
- X@open eat
- X@link eat = here
- X@lock eat = something_impossible
- X@fail eat = You try to eat but only gag
- X@ofail eat = tries to eat but instead gags
- X\end{verbatim}
- XThen when you use the command {\tt eat} the others in the room will
- Xsee {\tt Betty tries to eat but instead gags} and you'll see {\tt You
- Xtry to eat but only gag\/}.
- X
- XNote that this ``new command'' will only work in the room that you
- Xmade it in.
- X
- X\clearpage
- X
- X\part*{Appendix}
- X
- X\appendix
- X
- X\section{Wizard commands}
- X\label{sec:wizard-commands}
- X
- X\begin{simple}
- X
- X\item[]
- X\begin{flushleft}
- X{\tt @chown} $<${\em object\/}$>$ \verb|=| $<${\em player\/}$>$
- X\index{chown@\type{"@chown}}
- X\end{flushleft}
- XChanges the ownership of $<${\em object\/}$>$ to $<${\em player\/}$>$.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt @dump}
- X\index{dump@\type{"@dump}}
- X\end{flushleft}
- XForces a dump of the database. This command isn't really necessary
- Xsince {\tt @shutdown} does one as well as the regular periodic dumps.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt examine} $<${\em name\/}$>$ \\
- X{\tt examine} {\tt \#}$<${\em number\/}$>$
- X\index{examine@\type{examine}}
- X\end{flushleft}
- XPrint a detailed description of object specified by $<${\em name\/}$>$
- Xor by $<${\em number\/}$>$. All six strings listed in
- Xsection~\ref{sec:object-strings} are printed.
- X
- XWhen $<${\em name\/}$>$ is a room or {\tt
- Xhere}\index{here@\type{here}} it lists the owner, key, number of
- Xpennies, the description, contents, and exits. When $<${\em
- Xname\/}$>$ is a direction lists the direction number, owner, key,
- Xpennies, and destination.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt @force} $<${\em victim\/}$>$ \verb|=| $<${\em command\/}$>$
- X\index{force@\type{"@force}}
- X\end{flushleft}
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt @newpassword} $<${\em player\/}$>$ \verb|=| $<${\em
- Xpassword\/}$>$
- X\index{newpassword@\type{"@newpassword}}
- X\end{flushleft}
- XChanges the password for $<${\em player\/}$>$.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt @shutdown}
- X\index{shutdown@\type{"@shutdown}}
- X\end{flushleft}
- XShuts down the {\tinymud} server.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt @stats}
- X\index{stats@\type{"@stats}}
- X\end{flushleft}
- XLists the total number of objects, which is the sum of the rooms,
- Xexits, things, and players, giving the count for each one.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt @teleport} $[$ $<${\em victim\/}$>$ \verb|=| $]$ $<${\em
- Xdestination\/}$>$
- X\index{teleport@\type{"@teleport}}
- X\end{flushleft}
- XTeleports the object to the specified destination. Object can also be
- X{\tt me\/}.\index{me@\type{me}}
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt @toad} $<${\em player\/}$>$
- X\index{toad@\type{"@toad}}
- X\end{flushleft}
- XTurns $<${\em player\/}$>$ into an object.
- X
- X\dorule
- X
- X\item[]
- X\begin{flushleft}
- X{\tt @wall} $<${\em message\/}$>$
- X\index{wall@\type{"@wall}}
- X\end{flushleft}
- XSend $<${\em message\/}$>$ to all players.
- X
- X\end{simple}
- X
- X\addcontentsline{toc}{part}{Index}
- X
- X\printindex
- X
- X\end{document}
- END_OF_FILE
- if test 28102 -ne `wc -c <'tinymud.tex'`; then
- echo shar: \"'tinymud.tex'\" unpacked with wrong size!
- fi
- # end of 'tinymud.tex'
- fi
- echo shar: End of archive 7 \(of 10\).
- cp /dev/null ark7isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 10 archives.
- echo ">>> now type 'sh joinspl.sh'"
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-